package com.forest.oss.impl.huawei;

import cn.hutool.core.io.IoUtil;
import cn.hutool.core.lang.Assert;
import com.obs.services.ObsClient;
import com.obs.services.model.*;
import lombok.SneakyThrows;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.CollectionUtils;
import com.forest.oss.AbstractOssClient;
import com.forest.oss.constants.AclType;
import com.forest.oss.impl.OssProperties;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @Author:
 * @Description
 * @date 2022/11/2 10:30
 * @Version 1.0
 * 华为对象存储
 */
public class HuaweiOssClient extends AbstractOssClient {

    private static Logger log = LoggerFactory.getLogger(HuaweiOssClient.class);

    private HuaweiOssProperties huaweiOssProperties;
    private ObsClient client;

    public HuaweiOssClient(HuaweiOssProperties huaweiOssProperties) {
        System.out.println("--------------加载华为对象存储------------");
        this.huaweiOssProperties = huaweiOssProperties;
        this.client = getOssClient();
    }

    private ObsClient getOssClient() {
        return new ObsClient(huaweiOssProperties.getAppKeyId(),
                huaweiOssProperties.getAppSecret(),
                huaweiOssProperties.getEndPoint()
        );
    }

    @Override
    public OssProperties getProperties() {
        return this.huaweiOssProperties;
    }

    @Override
    public String getFolder() {
        return super.getFolder(huaweiOssProperties.getProject());
    }


    @Override
    @SneakyThrows
    public String upload(String key, String folder, InputStream inputStream, AclType acl) {
        // 上传同时设置访问权限
        ObjectMetadata metadata = new ObjectMetadata();
        metadata.setContentType(getContentType(key));
        try {
            metadata.setContentLength(Long.valueOf(inputStream.available()));
        } catch (IOException e) {
            log.error("获取文件流有限内容长度异常：{}", e.getMessage(), e);
        }
        PutObjectRequest request = new PutObjectRequest();
        request.setAcl(AclType.PublicRead.getHandler().equals(acl.getHandler()) ? AccessControlList.REST_CANNED_PUBLIC_READ : AccessControlList.REST_CANNED_PRIVATE);
        client.putObject(huaweiOssProperties.getBucket(), folder + key, inputStream, metadata);
        return folder + key;
    }

    @Override
    @SneakyThrows
    public InputStream download(String key) {
        ObsObject obsObject = getOssClient().getObject(huaweiOssProperties.getBucket(), key);
        InputStream objectContent = obsObject.getObjectContent();
        byte[] content = IoUtil.readBytes(objectContent);
        return new ByteArrayInputStream(content);
    }

    @Override
    @SneakyThrows
    public void delete(String key) {
        client.deleteObject(huaweiOssProperties.getBucket(), key);
    }

    @Override
    @SneakyThrows
    public List<String> batchDelete(List<String> keys, boolean quiet) {
        Assert.isTrue(CollectionUtils.isEmpty(keys), "删除的文件keys不能为空");
        Assert.isTrue(keys.size() > 1000, "删除的文件keys超过了最大限制1000个");
        DeleteObjectsRequest request = new DeleteObjectsRequest(huaweiOssProperties.getBucket());
        request.setQuiet(quiet);
        request.setKeyAndVersions(keys.stream().map(k-> new KeyAndVersion(k)).toArray(KeyAndVersion[]::new));
        DeleteObjectsResult result = client.deleteObjects(request);
        List<String> data = result.getDeletedObjectResults().stream().map(DeleteObjectsResult.DeleteObjectResult::getObjectKey).collect(Collectors.toList());
        return data;
    }

    @Override
    @SneakyThrows
    public String getFile(String key, AclType acl) {
        if(AclType.PublicRead.getHandler().equals(acl.getHandler())) {
            return buildPublicUrl(huaweiOssProperties.getBucketDomain(), key);
        } else {
            TemporarySignatureRequest request = new TemporarySignatureRequest(HttpMethodEnum.GET, 7 * 24 * 60 * 60);
            request.setObjectKey(key);
            request.setBucketName(huaweiOssProperties.getBucket());
            TemporarySignatureResponse temporarySignature = client.createTemporarySignature(request);
            String url = temporarySignature.getSignedUrl();
            return url;
        }
    }

    @Override
    public Boolean exists(String key) {
        GetObjectMetadataRequest request = new GetObjectMetadataRequest(huaweiOssProperties.getBucket(), key);
        return client.doesObjectExist(request);
    }
}
